package com.ssy.lingxi.pay.controller.mobile;

import cn.hutool.core.bean.BeanUtil;
import com.ssy.lingxi.common.constant.order.OrderPayChannelEnum;
import com.ssy.lingxi.common.controller.BaseController;
import com.ssy.lingxi.common.model.dto.UserLoginCacheDTO;
import com.ssy.lingxi.common.model.vo.PageVO;
import com.ssy.lingxi.common.response.PageData;
import com.ssy.lingxi.common.response.ResponseCode;
import com.ssy.lingxi.common.response.Wrapper;
import com.ssy.lingxi.member.merchant.api.feign.inner.MemberInnerControllerFeign;
import com.ssy.lingxi.member.merchant.api.model.vo.inner.response.MemberFeignLogoVO;
import com.ssy.lingxi.order.api.feign.OrderFeignService;
import com.ssy.lingxi.order.api.model.vo.request.OrderPayParameterFeignVO;
import com.ssy.lingxi.order.api.model.vo.response.PaymentParameterFeignDetailVO;
import com.ssy.lingxi.pay.api.dto.request.assetAccount.*;
import com.ssy.lingxi.pay.api.dto.response.assetAccount.*;
import com.ssy.lingxi.pay.entity.assetAccount.AccountStatusRecord;
import com.ssy.lingxi.pay.entity.assetAccount.AccountTradeRecord;
import com.ssy.lingxi.pay.entity.assetAccount.MemberAssetAccount;
import com.ssy.lingxi.pay.model.assetAccount.BalanceQueryVO;
import com.ssy.lingxi.pay.model.assetAccount.MemberAssetAccountQuery;
import com.ssy.lingxi.pay.service.assetAccount.IAccountStatusService;
import com.ssy.lingxi.pay.service.assetAccount.IAccountTradeService;
import com.ssy.lingxi.pay.service.assetAccount.IMemberAssetAccountService;
import org.modelmapper.TypeToken;
import org.springframework.data.domain.Page;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @menu: APP-资金账户管理
 * 资金账户
 * @author jw.chen
 * @version 2.0.0
 * @date 2020/12/28
 */
@RestController
@RequestMapping("/pay/mobile/assetAccount")
public class MobileAssetAccountController extends BaseController {

    @Resource
    private IMemberAssetAccountService memberAssetAccountService;

    @Resource
    private IAccountTradeService accountTradeService;

    @Resource
    private IAccountStatusService accountStatusService;

    @Resource
    private OrderFeignService orderFeignService;

    @Resource
    private MemberInnerControllerFeign memberInnerControllerFeign;

    /**
     * 查询资金账户列表(卡包)
     * @param pageVO 分页实体
     * @param assetAccountQueryRequest 参数
     */
    @RequestMapping(value = "/getAssetAccountList", method = RequestMethod.GET)
    public Wrapper<PageData<MemberAssetAccountResponse>> getAssetAccountList(PageVO pageVO, AssetAccountQueryRequest assetAccountQueryRequest) {
        UserLoginCacheDTO sysUser = this.getSysUser();
        Long memberId = sysUser.getMemberId();
        Long memberRoleId = sysUser.getMemberRoleId();
        Integer memberLevelType = sysUser.getMemberLevelType();
        MemberAssetAccountQuery memberAssetAccountMiddle = this.modelMapper.map(assetAccountQueryRequest, MemberAssetAccountQuery.class);
        memberAssetAccountMiddle.setMemberId(memberId);
        memberAssetAccountMiddle.setMemberRoleId(memberRoleId);

        //只查询商家会员账户
        List<Integer> memberLevelTypeList = new ArrayList<>();
        memberLevelTypeList.add(memberLevelType);
        memberAssetAccountMiddle.setMemberLevelTypeList(memberLevelTypeList);

        Page<MemberAssetAccount> result = memberAssetAccountService.getMemberAssetAccountList(pageVO, memberAssetAccountMiddle);
        List<MemberAssetAccount> memberAssetAccountList = result.getContent();
        if(memberAssetAccountList.size() > 0){
            HashMap<Long, String> map = new HashMap<>();
            //查询会员头像
            List<Long> memberIdList = memberAssetAccountList.stream().map(MemberAssetAccount::getMemberId).collect(Collectors.toList());
            Wrapper<List<MemberFeignLogoVO>> memberLogos = memberInnerControllerFeign.getMemberLogos(memberIdList);
            if(memberLogos != null && memberLogos.getCode() == ResponseCode.SUCCESS.getCode()){
                List<MemberFeignLogoVO> data = memberLogos.getData();
                data.forEach(memberFeignLogoVO -> map.put(memberFeignLogoVO.getMemberId(), memberFeignLogoVO.getLogo()));
            }
            //遍历设置logo
            List<MemberAssetAccountResponse> resultList = memberAssetAccountList.stream().map(memberAssetAccount -> {
                MemberAssetAccountResponse memberAssetAccountResponse = BeanUtil.copyProperties(memberAssetAccount, MemberAssetAccountResponse.class);
                memberAssetAccountResponse.setMemberLogo(map.get(memberAssetAccount.getId()));
                return memberAssetAccountResponse;
            }).collect(Collectors.toList());
            return Wrapper.success(new PageData<>(result.getTotalElements(), resultList));
        }else{
            return Wrapper.success(new PageData<>(0L, new ArrayList<>()));
        }
    }

    /**
     * 账户详情
     * @param id 资金账户id
     */
    @RequestMapping(value = "/getAssetAccount", method = RequestMethod.GET)
    public Wrapper<MemberAssetAccountResponse> getAssetAccount(@RequestParam Long id) {
        MemberAssetAccount memberAssetAccount = memberAssetAccountService.getMemberAssetAccount(id);
        if(memberAssetAccount != null){
            return Wrapper.success(this.modelMapper.map(memberAssetAccount, MemberAssetAccountResponse.class));
        }else{
            return Wrapper.success(null);
        }
    }

    /**
     * 查询平台账户详情
     */
    @RequestMapping(value = "/getPlatFormAssetAccount", method = RequestMethod.GET)
    public Wrapper<MemberAssetAccountResponse> getPlatFormAssetAccount() {
        UserLoginCacheDTO sysUser = this.getSysUser();
        MemberAssetAccount memberAssetAccount = memberAssetAccountService.getPlatFormAssetAccount(sysUser);
        if(memberAssetAccount != null){
            return Wrapper.success(this.modelMapper.map(memberAssetAccount, MemberAssetAccountResponse.class));
        }else{
            return Wrapper.success(null);
        }
    }

    /**
     * 查询会员用户的账户详情
     * @param parentMemberId 上级会员id
     * @param parentMemberRoleId 上级会员角色id
     */
    @RequestMapping(value = "/getUserAssetAccount", method = RequestMethod.GET)
    public Wrapper<MemberAssetAccountResponse> getUserAssetAccount(@RequestParam Long parentMemberId, @RequestParam Long parentMemberRoleId) {
        UserLoginCacheDTO sysUser = this.getSysUser();
        Long memberId = sysUser.getMemberId();
        Long memberRoleId = sysUser.getMemberRoleId();
        return Wrapper.success(memberAssetAccountService.getUserAssetAccount(memberId, memberRoleId, parentMemberId, parentMemberRoleId));
    }

    /**
     * 交易记录
     * @param tradeRecordRequest 参数
     */
    @RequestMapping(value = "/getAccountTradeRecord", method = RequestMethod.POST)
    public Wrapper<PageData<AccountTradeRecordResponse>> getAccountTradeRecord(@RequestBody TradeRecordRequest tradeRecordRequest) {
        Long memberAssetAccountId = tradeRecordRequest.getMemberAssetAccountId();
        List<Integer> operationList = tradeRecordRequest.getOperationList();
        Long startTime = tradeRecordRequest.getStartTime();
        Long endTime = tradeRecordRequest.getEndTime();

        PageVO pageVO = new PageVO();
        pageVO.setCurrent(tradeRecordRequest.getCurrent());
        pageVO.setPageSize(tradeRecordRequest.getPageSize());
        Page<AccountTradeRecord> result = accountTradeService.getAccountTradeRecordList(pageVO, memberAssetAccountId, operationList, startTime, endTime);
        List<AccountTradeRecordResponse> resultList = this.modelMapper.map(result.getContent(), new TypeToken<List<AccountTradeRecordResponse>>(){}.getType());
        return Wrapper.success(new PageData<>(result.getTotalElements(), resultList));
    }

    /**
     * 状态记录
     * @param memberAssetAccountId 会员资金账户id
     */
    @RequestMapping(value = "/getAccountStatusRecord", method = RequestMethod.GET)
    public Wrapper<List<AccountStatusRecord>> getAccountStatusRecord(@RequestParam("memberAssetAccountId") Long memberAssetAccountId) {
        return Wrapper.success(accountStatusService.getAccountStatusRecord(memberAssetAccountId));
    }

    /**
     * 账户充值(app)
     * @param rechargeRequest 参数
     */
    @RequestMapping(value = "/recharge", method = RequestMethod.POST)
    public Wrapper<AccountRechargeAppResponse> recharge(@RequestBody @Valid RechargeRequest rechargeRequest, HttpServletRequest request) {
        return Wrapper.success(memberAssetAccountService.rechargeAssetAccountApp(request, rechargeRequest));
    }

    /**
     * 账户充值(小程序)
     * @param rechargeAppletRequest 参数
     */
    @RequestMapping(value = "/rechargeApplet", method = RequestMethod.POST)
    public Wrapper<AccountRechargeAppletResponse> rechargeApplet(@RequestBody @Valid RechargeAppletRequest rechargeAppletRequest, HttpServletRequest request) {
        return Wrapper.success(memberAssetAccountService.rechargeAssetAccountApplet(request, rechargeAppletRequest));
    }

    /**
     * 账户充值(H5)
     * @param rechargeJsApiRequest 参数
     */
    @RequestMapping(value = "/rechargeJsApi", method = RequestMethod.POST)
    public Wrapper<AccountRechargeJsApiResponse> rechargeJsApi(@RequestBody @Valid RechargeJsApiRequest rechargeJsApiRequest, HttpServletRequest request) {
        return Wrapper.success(memberAssetAccountService.rechargeAssetAccountJsApi(request, rechargeJsApiRequest));
    }

    /**
     * 查询账户充值结果
     * @param tradeRecordId 交易记录id
     */
    @RequestMapping(value = "/getRechargeResult", method = RequestMethod.GET)
    public Wrapper<Boolean> getRechargeResult(@RequestParam("tradeRecordId") Long tradeRecordId) {
        return Wrapper.success(memberAssetAccountService.getRechargeResult(tradeRecordId));
    }

    /**
     * 申请提现
     * @param cashOutRequest 参数
     */
    @RequestMapping(value = "/cashOut", method = RequestMethod.POST)
    public Wrapper<String> cashOut(@RequestBody @Valid CashOutRequest cashOutRequest) {
        return Wrapper.success(memberAssetAccountService.cashOutAssetAccount(cashOutRequest));
    }

    /**
     * 余额支付
     * @param balancePayRequest 参数
     */
    @RequestMapping(value = "/balancePay", method = RequestMethod.POST)
    public Wrapper<String> balancePay(@RequestBody BalancePayRequest balancePayRequest) {
        return Wrapper.success(memberAssetAccountService.balancePay(balancePayRequest));
    }

    /**
     * 查询会员账户余额
     * @param queryVO 接口参数
     * @return 查询结果
     */
    @RequestMapping(value = "/balance", method = RequestMethod.GET)
    public Wrapper<Double> getAccountBalance(@Valid BalanceQueryVO queryVO) {
        UserLoginCacheDTO sysUser = this.getSysUser();
        Long memberId = sysUser.getMemberId();
        Long memberRoleId = sysUser.getMemberRoleId();
        return Wrapper.success(memberAssetAccountService.getUserBalance(queryVO.getFundMode(), memberId, memberRoleId, queryVO.getVendorMemberId(), queryVO.getVendorRoleId()));
    }

    /**
     * 查询登录用户的账户余额
     * @param parentMemberId 上级会员id
     * @param parentMemberRoleId 上级会员角色id
     */
    @RequestMapping(value = "/getUserBalance", method = RequestMethod.GET)
    public Wrapper<Double> getUserBalance(@RequestParam Long parentMemberId, @RequestParam Long parentMemberRoleId) {
        //查询当前用户的资金归集模式: 1-平台，2-会员
        //从会员服务查询资金归集模式
        OrderPayParameterFeignVO feignVO = new OrderPayParameterFeignVO();
        feignVO.setMemberId(parentMemberId);
        feignVO.setRoleId(parentMemberRoleId);
        feignVO.setPayChannel(OrderPayChannelEnum.ACCOUNT_BALANCE);
        Wrapper<PaymentParameterFeignDetailVO> parameterResult = orderFeignService.findPaymentParameters(feignVO);
        if(parameterResult.getCode() != ResponseCode.SUCCESS.getCode()) {
            return Wrapper.fail(parameterResult.getCode(), parameterResult.getMessage());
        }

        UserLoginCacheDTO sysUser = this.getSysUser();
        Long memberId = sysUser.getMemberId();
        Long memberRoleId = sysUser.getMemberRoleId();
        return Wrapper.success(memberAssetAccountService.getUserBalance(parameterResult.getData().getFundMode().getCode(), memberId, memberRoleId, parentMemberId, parentMemberRoleId));
    }

    /**
     * 查询登录用户的所有账户余额
     */
    @RequestMapping(value = "/getUserAllBalance", method = RequestMethod.GET)
    public Wrapper<Double> getUserAllBalance() {
        UserLoginCacheDTO sysUser = this.getSysUser();
        Long memberId = sysUser.getMemberId();
        Long memberRoleId = sysUser.getMemberRoleId();
        return Wrapper.success(memberAssetAccountService.getUserAllBalance(memberId, memberRoleId));
    }
}
